package com.sojson.util.file.interfaces.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.sojson.entity.po.FileDepot;
import com.sojson.service.FileDepotService;
import com.sojson.util.StringUtil;
import com.sojson.util.file.FileUtil;
import com.sojson.util.file.enums.EFileStatus;
import com.sojson.util.file.interfaces.FileDepotUtilInterface;

/**
 * 文件库工具类
 * 
 * @author liu
 * @date 2021-05-26
 */
@Component
public class FileDepotUtilImpl implements FileDepotUtilInterface {

    @Lazy
    @Autowired
    private FileDepotUtilImpl fileDepotUtilImpl;
    @Autowired
    private FileDepotService imageService;

    /**
     * 添加文件(本地文件)
     * 
     * @param newImg 上传接口返回的字符串
     */
    @Override
    public boolean uploadThisLocal(String newImg) {
        if (isBlank(newImg)) {
            return false;
        }

        FileDepot image = new FileDepot();
        image.insertInit();
        image.setUrl(newImg);
        image.setPath(newImg.substring(FileUtil.THIS_LOCALITY_DIRECTORY_BUCKET_NAME_BASE_URL.length()));
        return imageService.insert(image) > 0;
    }

    /**
     * 添加文件(文件存储系统文件)
     * 
     * @param newImg 上传接口返回的字符串
     */
    @Override
    public boolean upload(String newImg) {
        if (isBlank(newImg)) {
            return false;
        }

        FileDepot image = new FileDepot();
        image.insertInit();
        image.setUrl(newImg);
        image.setPath(newImg);
        return imageService.insert(image) > 0;
    }

    /**
     * 添加数据的时候修改文件(异步方法)
     * 
     * @param tableCode 表代码
     * @param fieldName 字段名
     * @param newImg    上传接口返回的字符串
     */
    @Async
    @Override
    @Transactional
    public void insert(int tableCode, String fieldName, String newImg) {
        fileDepotUtilImpl.insertSync(tableCode, fieldName, newImg);
    }

    /**
     * 添加数据的时候修改文件(同步方法)
     * 
     * @param tableCode 表代码
     * @param fieldName 字段名
     * @param newImg    上传接口返回的字符串
     */
    @Override
    @Transactional
    public boolean insertSync(int tableCode, String fieldName, String newImg) {
        if (isBlank(newImg)) {
            return true;
        }

        FileDepot image = new FileDepot();
        image.setTableCode(tableCode);
        image.setFieldName(fieldName);
        image.setKey(tableCode + "," + fieldName);
        image.setUrl(newImg);
        image.setStatus(EFileStatus.USE_YES.getCode());

        return imageService.updateByUrl(image) > 0;
    }

    /**
     * 添加数据的时候修改文件(异步方法)
     * 
     * @param tableCode 表代码
     * @param fieldName 字段名
     * @param newImg    上传接口返回的字符串
     */
    @Async
    @Override
    @Transactional
    public void insertList(int tableCode, String fieldName, String newImg) {
        fileDepotUtilImpl.insertListSync(tableCode, fieldName, newImg);
    }

    /**
     * 添加数据的时候修改文件(同步方法)
     * 
     * @param tableCode 表代码
     * @param fieldName 字段名
     * @param newImg    上传接口返回的字符串
     */
    @Override
    @Transactional
    public int insertListSync(int tableCode, String fieldName, String newImg) {
        if (isBlank(newImg)) {
            return 0;
        }

        FileDepot image = new FileDepot();
        image.setTableCode(tableCode);
        image.setFieldName(fieldName);
        image.setKey(tableCode + "," + fieldName);
        image.setUrlArr(newImg.split(","));
        image.setStatus(EFileStatus.USE_YES.getCode());

        return imageService.updateByUrlArr(image);
    }

    /**
     * 修改数据的时候修改文件(异步方法)
     * 
     * @param tableCode 表代码
     * @param fieldName 字段名
     * @param newImg    新文件
     * @param oldImg    旧文件
     */
    @Async
    @Override
    @Transactional
    public void update(int tableCode, String fieldName, String newImg, String oldImg) {
        fileDepotUtilImpl.updateSync(tableCode, fieldName, newImg, oldImg);
    }

    /**
     * 修改数据的时候修改文件(同步方法)
     * 
     * @param tableCode 表代码
     * @param fieldName 字段名
     * @param newImg    新文件
     * @param oldImg    旧文件
     */
    @Override
    @Transactional
    public boolean updateSync(int tableCode, String fieldName, String newImg, String oldImg) {
        if (isBlank(newImg) || newImg.equals(oldImg)) {
            return true;
        }

        FileDepot image = new FileDepot();

        // 将新文件改为使用中
        image.setTableCode(tableCode);
        image.setFieldName(fieldName);
        image.setKey(tableCode + "," + fieldName);
        image.setUrl(newImg);
        image.setStatus(EFileStatus.USE_YES.getCode());
        int updateStatusByUrl = imageService.updateByUrl(image);
        if (updateStatusByUrl < 1) {
            return false;
        }

        if (isBlank(oldImg)) {
            return true;
        }

        // 将旧文件改为未使用
        image.setUrl(oldImg);
        image.setStatus(EFileStatus.USE_NO.getCode());
        updateStatusByUrl = imageService.updateStatusByUrl(image);

        return true;
    }

    /**
     * 修改数据的时候修改文件(异步方法)
     * 
     * @param tableCode 表代码
     * @param fieldName 字段名
     * @param newImg    新文件
     * @param oldImg    旧文件
     */
    @Async
    @Override
    @Transactional
    public void updateList(int tableCode, String fieldName, String newImg, String oldImg) {
        fileDepotUtilImpl.updateListSync(tableCode, fieldName, newImg, oldImg);
    }

    /**
     * 修改数据的时候修改文件(同步方法)
     * 
     * @param tableCode 表代码
     * @param fieldName 字段名
     * @param newImg    新文件
     * @param oldImg    旧文件
     */
    @Override
    @Transactional
    public boolean updateListSync(int tableCode, String fieldName, String newImg, String oldImg) {
        if (isBlank(newImg) || newImg.equals(oldImg)) {
            return true;
        }
        String d = ",";
        List<String> newImgList = new ArrayList<>();
        List<String> oldImgList = new ArrayList<>();
        String[] newImgs = newImg.split(d);
        String[] oldImgs = null;
        if (isBlank(oldImg)) {
            oldImgs = new String[0];
        } else {
            oldImgs = oldImg.split(d);
        }
        int newLen = newImgs.length;
        int oldLen = oldImgs.length;
        boolean isCons = false;
        for (int i = 0; i < newLen; i++) {
            String newImage = newImgs[i];
            for (int j = 0; j < oldLen; j++) {
                if (newImage.equals(oldImgs[j])) {
                    isCons = true;
                    break;
                }
            }
            if (!isCons) {
                newImgList.add(newImage);
            }
            isCons = false;
        }

        FileDepot image = new FileDepot();

        // 将新文件改为使用中
        image.setTableCode(tableCode);
        image.setFieldName(fieldName);
        image.setKey(tableCode + "," + fieldName);
        image.setUrls(newImgList);
        image.setStatus(EFileStatus.USE_YES.getCode());
        int updateStatusByUrl = imageService.updateByUrlList(image);
        if (updateStatusByUrl < 1) {
            return false;
        }

        if (oldImgs.length == 0) {
            return true;
        }
        for (int i = 0; i < oldLen; i++) {
            String oldImage = oldImgs[i];
            for (int j = 0; j < newLen; j++) {
                if (oldImage.equals(newImgs[j])) {
                    isCons = true;
                    break;
                }
            }
            if (!isCons) {
                oldImgList.add(oldImage);
            }
            isCons = false;
        }

        // 将旧文件改为未使用
        image.setUrls(oldImgList);
        image.setStatus(EFileStatus.USE_NO.getCode());
        updateStatusByUrl = imageService.updateStatusByUrlList(image);

        return true;
    }

    /**
     * 删除数据的时候修改文件(异步方法)
     * 
     * @param oldImg 旧文件
     */
    @Async
    @Override
    @Transactional
    public void delete(String oldImg) {
        fileDepotUtilImpl.deleteSync(oldImg);
    }

    /**
     * 删除数据的时候修改文件(同步方法)
     * 
     * @param oldImg 旧文件
     */
    @Override
    @Transactional
    public boolean deleteSync(String oldImg) {
        if (isBlank(oldImg)) {
            return true;
        }

        FileDepot image = new FileDepot();
        image.setUrl(oldImg);

        // 将旧文件改为未使用
        image.setStatus(EFileStatus.USE_NO.getCode());

        return imageService.updateStatusByUrl(image) > 0;
    }

    /**
     * 删除数据的时候修改文件(异步方法)
     * 
     * @param oldImg 旧文件
     */
    @Async
    @Override
    @Transactional
    public void deleteList(String oldImg) {
        fileDepotUtilImpl.deleteListSync(oldImg);
    }

    /**
     * 删除数据的时候修改文件(同步方法)
     * 
     * @param oldImg 旧文件
     */
    @Override
    @Transactional
    public int deleteListSync(String oldImg) {
        if (isBlank(oldImg)) {
            return 0;
        }

        FileDepot image = new FileDepot();
        image.setUrlArr(oldImg.split(","));

        // 将旧文件改为未使用
        image.setStatus(EFileStatus.USE_NO.getCode());

        return imageService.updateStatusByUrlArr(image);
    }

    /**
     * 删除数据的时候修改文件(异步方法)
     * 
     * @param oldImg 旧文件
     */
    @Async
    @Override
    @Transactional
    public void deleteList(String[] oldImg) {
        fileDepotUtilImpl.deleteListSync(oldImg);
    }

    /**
     * 删除数据的时候修改文件(同步方法)
     * 
     * @param oldImg 旧文件
     */
    @Override
    @Transactional
    public int deleteListSync(String[] oldImg) {
        if (isBlank(oldImg) || oldImg.length == 0) {
            return 0;
        }

        List<String> arrayList = new ArrayList<>();
        for (String string : oldImg) {
            if (isNotBlank(string)) {
                arrayList.add(string);
            }
        }
        if (arrayList.size() == 0) {
            return 0;
        }
        FileDepot image = new FileDepot();
        image.setUrls(arrayList);

        // 将旧文件改为未使用
        image.setStatus(EFileStatus.USE_NO.getCode());

        return imageService.updateStatusByUrlList(image);
    }

    /**
     * 删除数据的时候修改文件(异步方法)
     * 
     * @param oldImg 旧文件
     */
    @Async
    @Override
    @Transactional
    public void deleteList(List<String> oldImg) {
        fileDepotUtilImpl.deleteListSync(oldImg);
    }

    /**
     * 删除数据的时候修改文件(同步方法)
     * 
     * @param oldImg 旧文件
     */
    @Override
    @Transactional
    public int deleteListSync(List<String> oldImg) {
        if (isBlank(oldImg) || oldImg.size() == 0) {
            return 0;
        }

        Iterator<String> iterator = oldImg.iterator();
        while (iterator.hasNext()) {
            String next = iterator.next();
            if (isBlank(next)) {
                iterator.remove();
            }
        }
        if (oldImg.size() == 0) {
            return 0;
        }
        FileDepot image = new FileDepot();
        image.setUrls(oldImg);

        // 将旧文件改为未使用
        image.setStatus(EFileStatus.USE_NO.getCode());

        return imageService.updateStatusByUrlList(image);
    }

    /**
     * 删除数据的时候修改文件(异步方法)
     * 
     * @param oldImg 旧文件
     */
    @Async
    @Override
    @Transactional
    public void deleteLists(List<String> oldImg) {
        fileDepotUtilImpl.deleteListsSync(oldImg);
    }

    /**
     * 删除数据的时候修改文件(同步方法)
     * 
     * @param oldImg 旧文件
     */
    @Override
    @Transactional
    public int deleteListsSync(List<String> oldImg) {
        if (isBlank(oldImg) || oldImg.size() == 0) {
            return 0;
        }

        List<String> arrayList = new ArrayList<>();
        for (String string : oldImg) {
            if (isNotBlank(string)) {
                String[] split = string.split(",");
                for (String spl : split) {
                    arrayList.add(spl);
                }
            }
        }
        if (arrayList.size() == 0) {
            return 0;
        }
        FileDepot image = new FileDepot();
        image.setUrls(arrayList);

        // 将旧文件改为未使用
        image.setStatus(EFileStatus.USE_NO.getCode());

        return imageService.updateStatusByUrlList(image);
    }

    /**
     * 删除旧文件
     * 
     * @param oldImg 上传接口返回的字符串
     */
    @Override
    public boolean deleteFile(String oldImg) {
        if (isBlank(oldImg)) {
            return true;
        }

        FileDepot image = new FileDepot();
        image.setUrl(oldImg);

        // 将旧文件改为已删除
        image.setStatus(EFileStatus.DELETE.getCode());

        return imageService.updateStatusByUrl(image) > 0;
    }

    /**
     * 删除旧文件
     * 
     * @param oldImgs 上传接口返回的字符串
     */
    @Override
    public int deleteFile(List<String> oldImgs) {
        if (oldImgs.size() < 1) {
            return 0;
        }

        FileDepot image = new FileDepot();
        image.setUrls(oldImgs);

        // 将旧文件改为已删除
        image.setStatus(EFileStatus.DELETE.getCode());

        return imageService.updateStatusByUrlList(image);
    }

    /**
     * 删除数据
     */
    @Override
    public int deleteData() {
        FileDepot image = new FileDepot();
        image.setStatus(EFileStatus.DELETE.getCode());
        return imageService.deleteByDto(image);
    }

    /**
     * 判断一个字符串是否是空(空对象和空字符串)
     * 
     * @param str
     * @return
     */
    private boolean isBlank(Object img) {
        return StringUtil.isBlank(img);
    }

    /**
     * 判断一个字符串是否不是空(空对象和空字符串)
     * 
     * @param str
     * @return
     */
    private boolean isNotBlank(Object img) {
        return StringUtil.isNotBlank(img);
    }

}